import json
from .iou import polygon_iou
import time
import ast

def eval_polygon_iou(bbox_score_cls, segment_pt, polygon_ROI, business_iou_thresh=0):
    bbox_score_cls_iou = []
    valid_segment_pt = []
    for i, one_segment_pt in enumerate(segment_pt):
        for one_roi in polygon_ROI:
            common_roi = []
            for pt in one_roi:
                common_roi.append(min(max(0, pt[0]), self.input_img_shape[1] - 1))  # x
                common_roi.append(min(max(0, pt[1]), self.input_img_shape[0] - 1))  # y
            iou_res = polygon_iou(one_segment_pt, common_roi)
            if iou_res > business_iou_thresh:
                valid_segment_pt.append(one_segment_pt) #由于性能问题，先不返回该分割点
                one_bbox_score_cls = bbox_score_cls[i]
                one_bbox_score_cls.append(iou_res)
                bbox_score_cls_iou.append(one_bbox_score_cls)

    return bbox_score_cls_iou, valid_segment_pt

def parse_alg_res_basedon_taskname(input_alg_res, input_ROIs=[[[0, 0], [1919, 0], [1919, 1079], [0, 1079]], ], thresh_IOU=0.0, object_type=["person"], thresh_confidence=0.1):
    """
    input_alg_res = '"{
                "code": 200,
                "message": "正常",
                "data": sys_data,
                "device_id": camera_key,
                "call_time": int(existed_img_data_list[-1][1]),
                "process_time": (int(time.time())),
                "img_path_list": [str(img_path)]
            }"'

    sys_data = {"projectId": "",
                "projectKey": IN_ALG_NAME_EN.upper(),
                "projectkey_cn": IN_ALG_NAME_CN,
                "projectList": str({"bbox_score_cls": bbox_score_cls, "segment_pt": segment_pt,
                    "classes_name": self.detector.classes, "label_pairs_dict": self.detector.label_pairs_dict}),
                }
    """
    try:
        print(f"input_alg_res: {input_alg_res}")  # Debug: Print input
        alg_res_dict = json.loads(input_alg_res)
        print(f"Parsed JSON alg_res_dict: {alg_res_dict}")  # Debug: Print parsed JSON
        if "data" not in alg_res_dict.keys() or "projectList" not in alg_res_dict["data"]:
            alg_res = {
                "code": 110,
                "message": "待拆分解析的算法结果的输入数据不正确，不包含data or projectList字段."
            }
            return json.dumps(alg_res, ensure_ascii=False)
        if not alg_res_dict["data"]["projectList"]:
            alg_res = {
                "code": 110,
                "message": "待拆分解析的算法结果的输入数据不正确，projectList字段值为空."
            }
            return json.dumps(alg_res, ensure_ascii=False)
        alg_pure_res_dict = ast.literal_eval(alg_res_dict["data"]["projectList"])
        print(f"alg_pure_res_dict:{alg_pure_res_dict}")
        required_keys = ["bbox_score_cls", "segment_pt", "classes_name", "label_pairs_dict"]
        is_key_all_existed = all(key in alg_pure_res_dict for key in required_keys)
        print(f"is_key_all_existed:{is_key_all_existed}")
        if not is_key_all_existed:
            alg_res = {
                "code": 110,
                "message": "待拆分解析的算法结果的输入数据不正确，不包含bbox_score_cls or segment_pt or classes_name or label_pairs_dict字段。"
            }
            return json.dumps(alg_res, ensure_ascii=False)
    except ValueError as e:
        return f"ValueError parse_alg_res_basedon_taskname: {str(e)}"   # 返回错误信息
    except Exception as e:
        return f"An error occurred parse_alg_res_basedon_taskname: {str(e)}"  # 捕获其他异常并返回错误信息

    bbox_score_cls = alg_pure_res_dict["bbox_score_cls"]
    segment_pt = alg_pure_res_dict["segment_pt"]
    classes_name = alg_pure_res_dict["classes_name"]
    label_pairs_dict = alg_pure_res_dict["label_pairs_dict"]

    if len(input_ROIs) == 0 or len(input_ROIs[0]) == 0:
        pass
    else:
        bbox_score_cls, segment_pt = eval_polygon_iou(bbox_score_cls, segment_pt, polygon_ROI=input_ROIs, business_iou_thresh=thresh_IOU)

    # 对输出结果进行筛选处理
    res_bboxes = []
    intrusion_total_cnts = 0
    identity_ID = 0
    group = 1
    for idx, pred in enumerate(bbox_score_cls):
        item = pred  # xmin ymin xmax ymax score class_id /iou
        if len(object_type) > 0 and classes_name[item[5]] not in object_type:  # 这里限定类别从用户业务参数输入
            continue
        if item[4] < thresh_confidence:
            continue
        identity_ID += 1
        one_res_dict = {}
        one_res_dict["key"] = classes_name[item[5]]
        one_res_dict["val"] = label_pairs_dict[classes_name[item[5]]]
        one_res_dict["group"] = group
        one_res_dict["id"] = identity_ID
        res_bboxes.append(one_res_dict)
        one_res_dict = {}
        one_res_dict["key"] = str(classes_name[item[5]] + "_bbox")
        one_res_dict["val"] = [[int(item[0]), int(item[1])], [int(item[2]), int(item[1])], [int(item[2]), int(item[3])], [int(item[0]), int(item[3])]]
        one_res_dict["group"] = group
        one_res_dict["id"] = identity_ID
        res_bboxes.append(one_res_dict)
        one_res_dict = {}
        one_res_dict["key"] = classes_name[int(item[5])] + "_confidence"
        one_res_dict["val"] = item[4]
        one_res_dict["group"] = group
        one_res_dict["id"] = identity_ID
        res_bboxes.append(one_res_dict)
        if len(input_ROIs) > 0:
            one_res_dict = {}
            one_res_dict["key"] = str(classes_name[item[5]] + "_iou")
            one_res_dict["val"] = item[6]
            one_res_dict["group"] = group
            one_res_dict["id"] = identity_ID
            res_bboxes.append(one_res_dict)
        """
        one_res_dict = {}
        one_res_dict["key"] = str(classes_name[item[5]] + "_segment_pt")
        pt = []
        for inner_i in range(0, len(segment_pt[idx]), 2):
            pt.append([segment_pt[idx][inner_i], segment_pt[idx][inner_i+1]])
        one_res_dict["val"] = pt
        one_res_dict["group"] = group
        one_res_dict["id"] = identity_ID
        res_bboxes.append(one_res_dict)
        """
        intrusion_total_cnts += 1
    if len(res_bboxes) > 0:
        one_res_dict = {}
        one_res_dict["key"] = "intrusion_count"
        one_res_dict["val"] = intrusion_total_cnts
        one_res_dict["group"] = 2
        one_res_dict["id"] = 1
        res_bboxes.append(one_res_dict)

        # 使用下划线连接列表中的值
        src_task_name = alg_res_dict["data"]["projectKey"]
        bus_task_name = ('_'.join(object_type) + src_task_name).upper()
        alg_res_dict["data"]["projectKey"] = bus_task_name
        alg_res_dict["data"]["projectList"] = str(res_bboxes)
    else:  # 算法无结果时直接返回None
        alg_res_dict = {
            "code": 120,
            "message": "目标分割算法无检测结果"
        }
    return json.dumps(alg_res_dict, ensure_ascii=False)

if __name__ == "__main__":
    IN_ALG_NAME_EN = "Object_Segmentation"
    IN_ALG_NAME_CN = "目标分割"

    sys_data = {"projectId": "",
                "projectKey": IN_ALG_NAME_EN.upper(),
                "projectkey_cn": IN_ALG_NAME_CN,
                "projectList": str({"bbox_score_cls": [], "segment_pt": [], "classes_name": "", "label_pairs_dict": ""})
                }

    alg_res = {
        "code": 200,
        "message": "正常",
        "data": sys_data,
        "device_id": 3,
        "call_time": int(time.time()),
        "process_time": (int(time.time())),
        "img_path_list": []
    }

    input_alg_res = json.dumps(alg_res, ensure_ascii=False)
    input_ROIs = [[[0, 0], [1919, 0], [1919, 1079], [0, 1079]], ]
    thresh_IOU = 0.0
    object_type = ["person"]
    thresh_confidence = 0.1
    alg_split_res = parse_alg_res_basedon_taskname(input_alg_res, input_ROIs=input_ROIs, thresh_IOU=thresh_IOU, object_type=object_type, thresh_confidence=thresh_confidence)
    print(alg_split_res)